﻿using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor.UIElements;
using System.Collections.Generic;
using System;
using System.Linq;
namespace WzhEditor.PrefabDeal
{
    /// <summary>预制体 处理窗口</summary>
    public class PrefabDealBaseWindow : EditorWindow
    {

        private VisualElement topVE;
        private VisualElement addView;
        private Button startBtn;
        private ListView prefabListView;
        private GameObject[] AllPrefab;

        private Func<GameObject, bool> ConvertPrefabCallBack;

        public void CreateGUI()
        {
            VisualElement root = rootVisualElement;

            var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/CommonModule/Editor/PrefabDeal/UI/PrefabDealBaseWindeow.uxml");
            visualTree.CloneTree(root);

            topVE = root.Q<VisualElement>("Top");
            addView = root.Q<VisualElement>("AddView");
            startBtn = root.Q<Button>("StartBtn");
            startBtn.clicked += OnStartBtn;

            prefabListView = root.Q<ListView>("PrefabList");
            prefabListView.makeItem = OnMakeItem;
            prefabListView.bindItem = OnBindItem;
            //prefabList.onSelectionChange += OnSelectItems;
        }

        private void InitWindeow(List<VisualElement> addViewList, Func<GameObject, bool> convertPrefabCallBack)
        {
            //添加 额外的数据显示
            if (addViewList != null)
                foreach (var item in addViewList)
                    addView.Add(item);

            this.ConvertPrefabCallBack = convertPrefabCallBack;

            var selectPaths = EditPathTool.GetSelectionPaths();
            var AllPaths = EditPathTool.GetAllPath(selectPaths);
            AllPrefab = GetPathAllPrefab(AllPaths).ToArray();
            prefabListView.itemsSource = AllPrefab;
        }

        private List<GameObject> GetPathAllPrefab(List<string> folderPath)
        {
            var objList = EditAssetTool.GetAllAsset<GameObject>(folderPath, "prefab");
            return objList;
        }
        private VisualElement OnMakeItem()
        {
            var ve = new ObjectField();
            ve.objectType = typeof(GameObject);
            return ve;
        }

        private void OnBindItem(VisualElement arg1, int arg2)
        {
            var nameTxt = arg1 as ObjectField;
            var go = AllPrefab[arg2];
            nameTxt.SetValueWithoutNotify(go);
        }

        private void OnStartBtn()
        {
            if (ConvertPrefabCallBack == null) return;
            if (AllPrefab == null) return;
            foreach (var item in AllPrefab)
            {
                if (ConvertPrefabCallBack.Invoke(item) == false) continue;
            }
            Close();
        }

        #region 预制体 处理方法

        private const string MenuPath = EditPathTool.MenuPath + "预制体处理/";


        [MenuItem(MenuPath + "名字加前后缀")]
        public static void ShowWindow1()
        {
            PrefabDealBaseWindow window = GetWindow<PrefabDealBaseWindow>();
            window.titleContent = new GUIContent("名字加前后缀");
            List<VisualElement> addViewList = new List<VisualElement>();
            TextField pexLabel = new TextField();
            pexLabel.label = "前缀";
            pexLabel.value = "";
            TextField exLabel = new TextField();
            exLabel.label = "后缀";
            exLabel.value = "";

            addViewList.Add(pexLabel);
            addViewList.Add(exLabel);

            Debug.Log($"PrefabDealBaseWindow 名字加前后缀");
            window.InitWindeow(addViewList, (obj) =>
            {
                string newName = $"{pexLabel.text}{obj.name}{exLabel.text}";
                EditAssetTool.RenameAsset(obj, newName);
                return true;
            });
        }
        [MenuItem(MenuPath + "替换名字字符")]
        public static void ShowWindow2()
        {
            PrefabDealBaseWindow window = GetWindow<PrefabDealBaseWindow>();
            window.titleContent = new GUIContent("替换名字字符");
            List<VisualElement> addViewList = new List<VisualElement>();
            TextField pexLabel = new TextField();
            pexLabel.label = "替换前";
            pexLabel.value = "";
            TextField exLabel = new TextField();
            exLabel.label = "替换后";
            exLabel.value = "";

            addViewList.Add(pexLabel);
            addViewList.Add(exLabel);

            Debug.Log($"PrefabDealBaseWindow 替换名字字符");
            window.InitWindeow(addViewList, (obj) =>
            {
                if (string.IsNullOrEmpty(pexLabel.value)) return false;

                string oldName = obj.name;
                string newName = oldName.Replace(pexLabel.value, exLabel.value);
                EditAssetTool.RenameAsset(obj, newName);
                return true;
            });
        }

        [MenuItem(MenuPath + "添加子物体")]
        public static void ShowWindow3()
        {
            PrefabDealBaseWindow window = GetWindow<PrefabDealBaseWindow>();
            window.titleContent = new GUIContent("添加子物体");
            List<VisualElement> addViewList = new List<VisualElement>();
            var m_objectField = new ObjectField();
            m_objectField.objectType = typeof(GameObject);
            m_objectField.label = "子预制";

            addViewList.Add(m_objectField);

            Debug.Log($"PrefabDealBaseWindow 添加子物体");
            window.InitWindeow(addViewList, (obj) =>
            {
                // 检查是否是预制体
                if (PrefabUtility.IsPartOfPrefabAsset(obj) == false) return false;

                var go = m_objectField.value as GameObject;
                if (go == null) return false;
                if (obj == go) return false;

                // 加载并实例化预制体
                GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(obj);
                GameObject childTrans = null;
                if (PrefabUtility.IsPartOfPrefabAsset(go))//预制物体
                {
                    childTrans = (GameObject)PrefabUtility.InstantiatePrefab(go);
                }
                else//一般物体
                {
                    childTrans = GameObject.Instantiate(go);
                    childTrans.name = go.name;
                }
                if (childTrans == null) return false;
                childTrans.transform.SetParent(instance.transform);

                // 最后再将实例化后的Prefab Apply重写
                PrefabUtility.ApplyPrefabInstance(instance, InteractionMode.AutomatedAction);

                // 删除实例
                DestroyImmediate(instance);
                return true;
            });
        }

        [MenuItem(MenuPath + "删除子物体")]
        public static void ShowWindow4()
        {
            PrefabDealBaseWindow window = GetWindow<PrefabDealBaseWindow>();
            window.titleContent = new GUIContent("1111");
            List<VisualElement> addViewList = new List<VisualElement>();
            TextField pexLabel = new TextField();
            pexLabel.label = "路径 (null:全部删除)";
            pexLabel.value = "";
      
            addViewList.Add(pexLabel);

            Debug.Log($"PrefabDealBaseWindow 删除子物体");
            window.InitWindeow(addViewList, (obj) =>
            {
                // 检查是否是预制体
                if (PrefabUtility.IsPartOfPrefabAsset(obj) == false) return false;
                // 加载并实例化预制体
                GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(obj);
                PrefabUtility.UnpackPrefabInstance(instance, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);

                if (string.IsNullOrEmpty(pexLabel.value))
                {
                    var children = instance.transform.Cast<Transform>().ToList();
                    foreach (var child in children)
                        Undo.DestroyObjectImmediate(child.gameObject);
                }
                else
                {
                    Transform childTrans = instance.transform.Find(pexLabel.value);
                    if (childTrans != null) Undo.DestroyObjectImmediate(childTrans.gameObject);
                }

                string assetPath = AssetDatabase.GetAssetPath(obj);
                PrefabUtility.SaveAsPrefabAsset(instance, assetPath);
                Undo.DestroyObjectImmediate(instance);
                return true;
            });
        }

        [MenuItem(MenuPath + "检查网格面超300")]
        public static void ShowWindow5()
        {
            PrefabDealBaseWindow window = GetWindow<PrefabDealBaseWindow>();
            window.titleContent = new GUIContent("检查网格面超300");
            
            window.InitWindeow(null, (obj) =>
            {
                // 检查是否是预制体
                if (PrefabUtility.IsPartOfPrefabAsset(obj) == false) return false;
                //GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(obj);

                var meshS = obj.GetComponentsInChildren<MeshFilter>();
                if (meshS == null || meshS.Length == 0) return false;
                int vertexCount = 0;
                foreach (var item in meshS)
                {
                    if (item.sharedMesh == null) continue;
                    vertexCount = item.sharedMesh.vertexCount;
                    if (vertexCount < 290) continue;
                    Debug.Log($"网格面超300  Prefab:{obj.name} {item.transform.parent.name}  {item.name}  {vertexCount}");
                }
                //Undo.DestroyObjectImmediate(instance);
                return false;
            });
        }
        #endregion
    }
}
